package org.example.domain.strategy.service.rule.chain.factory;

import lombok.*;
import org.example.domain.strategy.model.entity.StrategyEntity;
import org.example.domain.strategy.repository.IStrategyRepository;
import org.example.domain.strategy.service.rule.chain.ILogicChain;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 工厂
 */
@Service
public class DefaultChainFactory {
    //logicChainGroup 是 Spring 容器注入的 “规则节点 Map”，key 是规则标识（如 "rule_blacklist"、"default"）
    // value 是对应的规则节点实例（如 BlackListLogicChain、DefaultLogicChain）。
    //private final Map<String, ILogicChain> logicChainGroup;

    // 原型模式获取对象
    private final ApplicationContext applicationContext;
    // 仓储信息
    protected IStrategyRepository repository;
    // 存放策略链，策略ID -> 责任链
    private final Map<Long, ILogicChain> strategyChainGroup;

    public DefaultChainFactory(ApplicationContext applicationContext, IStrategyRepository repository) {
        this.applicationContext = applicationContext;
        this.repository = repository;
        this.strategyChainGroup = new ConcurrentHashMap<>();
    }
    /**
     * 查看rule_models里的规则
     * @param strategyId
     * @return
     */
    public ILogicChain openLogicChain(Long strategyId) {
        ILogicChain cacheLogicChain = strategyChainGroup.get(strategyId);
        if (null != cacheLogicChain) return cacheLogicChain;

        // 1. 查询策略配置的规则顺序（比如 ["rule_blacklist", "rule_weight"]
        StrategyEntity strategyEntity = repository.queryStrategyEntityByStrategyId(strategyId);
        String[] ruleModels = strategyEntity.ruleModels();

        if (ruleModels == null || ruleModels.length == 0) {
            //使用get(key)来回去map里的value值-名为default的节点实例
            ILogicChain ruleDefaultLogicChain = applicationContext.getBean(LogicModel.RULE_DEFAULT.getCode(), ILogicChain.class);
            // 写入缓存
            strategyChainGroup.put(strategyId, ruleDefaultLogicChain);
            return ruleDefaultLogicChain;

        }

        //获得责任链，执行顺序按照rule_models里面配置的来
        ILogicChain logicChain = applicationContext.getBean(ruleModels[0], ILogicChain.class);
        //将所有的节点串联起来，只是串联，不做逻辑判断。构造顺序链。
        //current相当于一个“指针”，指向当前链表的最后一个节点，通过appendNext节点调用再将新节点串起来
        ILogicChain current = logicChain;
        for (int i = 1; i < ruleModels.length; i++) {
            ILogicChain nextChain = applicationContext.getBean(ruleModels[i], ILogicChain.class);
            current = current.appendNext(nextChain);
        }
        //不管role_model里是什么，最后都要串起来兜底政策
        current.appendNext(applicationContext.getBean(LogicModel.RULE_DEFAULT.getCode(), ILogicChain.class));
        // 写入缓存
        strategyChainGroup.put(strategyId, logicChain);


        //最后返回责任链的第一个节点
        return logicChain;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class StrategyAwardVO {
        /** 抽奖奖品ID - 内部流转使用 */
        private Integer awardId;
        /**  */
        private String logicModel;
    }

    @Getter
    @AllArgsConstructor
    public enum LogicModel {

        RULE_DEFAULT("rule_default", "默认抽奖"),
        RULE_BLACKLIST("rule_blacklist", "黑名单抽奖"),
        RULE_WEIGHT("rule_weight", "权重规则"),
        ;

        private final String code;
        private final String info;

    }


}
